package cn.bytepath.log.aspect;

import cn.bytepath.annotation.Description;
import cn.bytepath.log.domain.UserLog;
import cn.bytepath.log.mapper.UserLogMapper;
import cn.bytepath.util.GetHttpResources;
import lombok.extern.slf4j.Slf4j;
import net.minidev.json.JSONArray;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * 用户日志的切面类
 * @author Jack.C
 * @createDate 2022-02-07
 * @version 1.0
 */
@Aspect
@Component
@Slf4j
public class UserLogAspect {

//    @Pointcut("execution(* cn.itsource._05aoptestannotation.service..*(..))")
//    @Pointcut("execution(* cn.bytepath.*.service..*.*(..)) && !execution(* cn.bytepath.log.service..*.*(..))")
    @Pointcut("execution(* cn.bytepath.*.service..*(..))")
    public void pointCut() {}

    @Autowired
    private UserLogMapper userLogMapper;

    @Around("pointCut()")
    public Object log(ProceedingJoinPoint pjp) {

        // 目标类(被代理类)的名称
        String className = pjp.getTarget().getClass().getName();
        // 方法名称
        String methodName = pjp.getSignature().getName();

        // 请求的参数列表
        Object[] args = pjp.getArgs();
        HttpServletRequest req = GetHttpResources.getRequest();
        String clientIpAddr = GetHttpResources.getClientIpAddr(req);

        Description annotationMethod = ((MethodSignature) pjp.getSignature()).getMethod().getAnnotation(Description.class);

        Description annotationClass = pjp.getTarget().getClass().getAnnotation(Description.class);
        String valueMethod = null;
        String valueClass = null;
        String description = null;
        if(annotationMethod != null && annotationClass != null) {
            valueMethod = annotationMethod.value();
            valueClass = annotationClass.value();
            description = valueMethod.replace("#", valueClass);
        } else {
            description = "未设置方法描述(无Description注解)";
        }

        long beginTime = System.currentTimeMillis();
        Object result = null;
        Long costTime = null;
        try {
            result = pjp.proceed();
            costTime = System.currentTimeMillis() - beginTime;
//            recordLog(pjp, costTime);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
//            recordLog(pjp, throwable.getMessage());
        }
        UserLog userLog = new UserLog();
        userLog.setIp(clientIpAddr);
        userLog.setMethod("类名:" + className + "; 方法名:" + methodName + "。");
        userLog.setCostTime(String.valueOf(costTime));
        userLog.setUsername("阿伟超勇超会喝");
        userLog.setDescription(description);
        userLogMapper.save(userLog);
        System.out.println(className + ":" + methodName + ":" + clientIpAddr + ":" + costTime);
        System.out.println(costTime + "---" + valueMethod);
        System.out.println(description);
        return result;

    }

    private void recordLog(ProceedingJoinPoint pjp, Long costTime) {
        // 目标类(被代理类)的名称
        String className = pjp.getTarget().getClass().getName();
        // 方法名称
        String methodName = pjp.getSignature().getName();
        // 参数列表
//        Parameter[] parameters = ((MethodSignature) pjp.getSignature()).getMethod().getParameters();
//        Object[] args = joinPoint.getArgs();

    }
    private void recordLog(ProceedingJoinPoint pjp, String msg) {
    }
}
